package com.vgemv.jsutilitysdk.Display.JsDisplayManagerBet;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;

import com.vgemv.jsutilitysdk.Reminder.JsLoadingReminderStandard1;
import com.vgemv.jsutilitysdk.Reminder.JsReminderManager;
import com.vgemv.jsutilitysdk.log.JsLogManager;

//TODO: window需要让子view可以点击,但是本身能穿透事件.

/**
 * 显示到SystemWindow
 */
public class JsDisplayManagerBet {

    public static Context mContext;
    public static WindowManager mWindowManager;

    public static View mView_loading;
    public static int mi_loadingCount;

    public static int mi_screenHeight;
    //从系统获取的高度
    public static int mi_applicationAreaHeight;
    //计算得来的应用程序区域高度=屏幕高度-状态栏高度.
    public static int mi_applicationAreaHeight_calculate;
    public static int mi_screenWidth;
    public static int mi_statusBarHeight;

    public static boolean mb_isActivityWindow;

    public  static Activity activity;

    //主线程的Handler
    private static final Handler mHandler_main = new Handler(Looper.getMainLooper());

    /** 窗口参数 */
    public static WindowManager.LayoutParams mLayoutParams_display;

    public static void init(Context context) {
        mContext =  context;
        if(mLayoutParams_display == null) {
            mLayoutParams_display = new WindowManager.LayoutParams();
            if (context instanceof Application) {
                //如果是系统级别的弹窗,必须设置type为SYSTEM_ALERT
                //application启动的window是没有token的,不能设置为Activity级别的type;
                Application application = (Application) context;
                mWindowManager = (WindowManager) application.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
                //默认是2,TYPE_APPLICATION
//            int type = mLayoutParams_display.type;
                mLayoutParams_display.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;

                mb_isActivityWindow = false;
                // 设置成全局的悬浮窗，注意需要先申请悬浮窗权限，推荐使用：https://github.com/getActivity/XXPermissions
                // 全局window
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//                mLayoutParams_display.type = (WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
//            } else {
//                mLayoutParams_display.type = (WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//            }
            } else {
                mb_isActivityWindow = true;
                mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//            mLayoutParams_display.type = WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
            }
        }





//        }


        //这里宽高影响的是window的宽高.
        //2114,手机里显示的是2244啊?少了130; 但是状态栏只有110,还有20是什么???
        mi_screenHeight = getDeviceSize(mContext).y;
        mi_applicationAreaHeight = getApplicationAreaHeight(mContext);
        mi_statusBarHeight = getStatusBarHeight(mContext);
        mi_applicationAreaHeight_calculate = mi_screenHeight - mi_statusBarHeight;
        mi_screenWidth = getScreenWidth(mContext);

        JsLogManager.logc_d("xxx","The screen width is %d, height is %d",mi_screenWidth,mi_screenHeight);


        if(mb_isActivityWindow) {
            //Activity级别的window,设置为Match_parent,并不会显示全屏.状态栏始终会在我们的activity的window上方.
            //只能手动补全
            //如果设置为Top,始终从状态栏下方开始绘制.但是会覆盖导航栏
            //如果设置为Center,中间在状态栏下方的中心.
            mLayoutParams_display.height = mi_applicationAreaHeight_calculate;

            mLayoutParams_display.width = mi_screenWidth;
            mLayoutParams_display.gravity = Gravity.TOP;

        }
        else {
            mLayoutParams_display.height = ViewGroup.LayoutParams.MATCH_PARENT;
            mLayoutParams_display.width = ViewGroup.LayoutParams.MATCH_PARENT;
            mLayoutParams_display.gravity = Gravity.CENTER;
        }



//        mLayoutParams_display.height =300;
//        mLayoutParams_display.width = 300;
        mLayoutParams_display.alpha = 1;
        //窗口设置为透明
        mLayoutParams_display.format = PixelFormat.TRANSLUCENT;

        //这个是啥??
//        mLayoutParams_display.windowAnimations = android.R.style.Animation_Toast;
        mLayoutParams_display.packageName = context.getPackageName();
        // 开启窗口常亮和设置可以触摸外层布局（除 WindowManager 外的布局，默认是 WindowManager 显示的时候外层不可触摸）
        // 需要注意的是设置了 FLAG_NOT_TOUCH_MODAL 必须要设置 FLAG_NOT_FOCUSABLE，否则就会导致用户按返回键无效
//        mLayoutParams_display.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
//                |
//                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

        // 如果当前 Activity 是全屏模式，那么需要添加这个标记，否则会导致 WindowManager 在某些机型上移动不到状态栏的位置上
        // 如果不想让状态栏显示的时候把 WindowManager 顶下来，可以添加 FLAG_LAYOUT_IN_SCREEN，但是会导致软键盘无法调整窗口位置
        addWindowFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
//        addWindowFlags(WindowManager.LayoutParams.TYPE_STATUS_BAR);
        addWindowFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
//        addWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
//        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
    }


    /**
     * 是否有这个标志位
     */
    public boolean hasWindowFlags(int flags) {
        return (mLayoutParams_display.flags & flags) != 0;
    }

    /**
     * 添加一个标记位
     */
    public static void addWindowFlags(int flags) {
        mLayoutParams_display.flags |= flags;
    }

    /**
     * 移除一个标记位
     */
    public static void clearWindowFlags(int flags) {
        mLayoutParams_display.flags &= ~flags;
    }

    /**
     * 设置标记位
     */
    public static void setWindowFlags(int flags) {
        mLayoutParams_display.flags = flags;
    }


    /*
     *
     */
    public static int getScreenWidth(Context ctx){
        DisplayMetrics dm = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }

    /**
     * 设置窗口背景阴影强度
     */
    public static void setBackgroundDimAmount(float amount) {
        if (amount < 0 || amount > 1) {
            throw new IllegalArgumentException("are you ok?");
        }
        mLayoutParams_display.dimAmount = amount;
        int flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
        if (amount != 0) {
            addWindowFlags(flags);
        } else {
            clearWindowFlags(flags);
        }
    }


    /**
     * 是否外层可触摸
     */
    public static void setOutsideTouchable(boolean touchable) {
        int flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        if (touchable) {
            addWindowFlags(flags);
        } else {
            clearWindowFlags(flags);
        }
    }

    //FIXME: height is not right;
    /**
     *
     *这个高度并不是全屏的高度,是ScreenHeight-StatusBarHegiht-Padding.
     * 小米的padding=20;
     * @param ctx
     * @return
     */
    public static int getApplicationAreaHeight(Context ctx){
        DisplayMetrics dm = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }

    public static int getApplicationDisplayHeight2(Context context) {
        Resources resources = context.getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        return dm.heightPixels;
//        System.out.println("heigth2 : " + dm2.heightPixels);
//        System.out.println("width2 : " + dm2.widthPixels);
    }

    //屏幕尺寸分为两种,设备尺寸和应用程序显示尺寸.
    public static Point getDeviceSize(Context context) {
        Point point = new Point();
        mWindowManager.getDefaultDisplay().getRealSize(point);
        return point;
    }

    //获取屏幕分辨率
    public static float getScreenDensity(){
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        return dm.density;
    }

    public static void display(View subview, View superview, JsDisplayStyle style) {

    }

    public static void undisplay(View subview, View superview, JsDisplayStyle style) {

    }

    public static void displayLoadingReminder(Activity activity) {
        JsLogManager.logc_d("xx","JsDisplayManagerBet/displayLoadingIndicator");

        if(mView_loading == null) {
            View view = getLoadingReminderViewStandard1(mContext);
            mView_loading = view;
            mi_loadingCount = 1;
            try {
                mWindowManager.addView(mView_loading, mLayoutParams_display);
            }
            catch (Exception e) {
                //is your activity running?  TYPE_TOAST,TYPE_SYSTEM_OVERLAY,TYPE_SYSTEM_DIALOG  LAST_APPLICATION_WINDOW,TYPE_APPLICATON,TYPE_APPLICATION_STARTING,TYPE_DRAWN_APPLICATION
                //LAST_APPLICATION_WINDOW,FIRST_SUB_WINDOW,TYPE_APPLICATION_MEDIA,LAST_SUB_WINDOW,TYPE_ACCESSIBILITY_OVERLAY

                //TYPE_SYSTEM_ALERT可以添加  TYPE_APPLICATION_OVERLAY


                //TYPE_PHONE,  permission LAST_SYSTEM_WINDOW,FIRST_SYSTEM_WINDOW,LAST_SYSTEM_WINDOW
                e.printStackTrace();
            }
        }
        else {
            mi_loadingCount ++;
        }
    }

    public static void undisplayLoadingIndicator() {
//        //GajLogManager.log(.log("GajDisplayManager/undisplayLoadingIndicator");
        mi_loadingCount --;
        if(mi_loadingCount == 0) {
            mWindowManager.removeView(mView_loading);
            mView_loading = null;
        }
    }
    public static void displayMessage(String message) {
//        //GajLogManager.log(.log("GajDisplayManager/displayMessage");
        displayMessage(message, JsDisplayStyle.defaultStyle());
    }


    public static void displayMessage(String message, final JsDisplayStyle style) {
        displayMessage(message,null,style);
    }


    public static void displayMessage(String message, Drawable drawable, final JsDisplayStyle style) {
//        //GajLogManager.log(.log("GajDisplayManager/displayMessage");

        //生成conentView,根据是否指定图片
        View contentView = null;
        if(drawable != null) {
            contentView = JsReminderManager.getMessageReminderIl(drawable, message, mContext);
        }
        else {
            contentView = JsReminderManager.getMessageRemindL(mContext,message);
        }

        //生成reminder,添加遮罩
        final View reminder = generateReminderView(contentView,style);

        //addView
        mWindowManager.addView(reminder, mLayoutParams_display);
        style.mb_isReminderDisplaying = true;
        //处理maskview的点击事件.
        if(style.mb_isNeedMaskView&&style.mb_isMaskViewClickCancel) {
            //可以点击,需要将window移除不可点击
            clearWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
            style.mv_mask.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    undisplayReminder(reminder,style);
                }
            });
        }
        else {
            //不需要点击,window设置为不可点击.
            addWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        }

        mHandler_main.postDelayed(new Runnable() {
            @Override
            public void run() {
                undisplayReminder(reminder,style);
            }
        },3000);
    }

    public static void undisplayReminder(View reminder, JsDisplayStyle style) {
        if(style.mb_isReminderDisplaying) {
            style.mb_isReminderDisplaying = false;
            mWindowManager.removeView(reminder);
        }
    }

    public static View generateReminderView(final View contentView, JsDisplayStyle style) {
        FrameLayout container = new FrameLayout(mContext);
        //TODO: Get real height screen;
        FrameLayout.LayoutParams lp_full = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
        lp_full.gravity = Gravity.CENTER;
        container.setLayoutParams(lp_full);


        View maskView = null;
        if(style.mb_isNeedMaskView) {
            maskView = new View(mContext);
            style.mv_mask = maskView;
            maskView.setLayoutParams(lp_full);
            maskView.setBackgroundColor(0x77333333);
            container.addView(maskView);
            maskView.setClickable(true);
//            maskView.setOnClickListener(new View.OnClickListener() {
//                @Override
//                public void onClick(View v) {
//                    //GajLogManager.log(.log("Click mask view...");
//                }
//            });


        }




        //一个view的layoutParams用来告诉父视图,如何布局自己,使用contentView本身设置的宽高.
//        ViewGroup.LayoutParams lp_originContent = contentView.getLayoutParams();
        style.mv_content = contentView;
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);
        lp.gravity = Gravity.CENTER;
        contentView.setLayoutParams(lp);
        container.addView(contentView);

        return container;
    }


    public static View getLoadingReminderViewStandard1(Context context) {
        FrameLayout container = new FrameLayout(context);
        //TODO: Get real height screen;
        FrameLayout.LayoutParams lp_full = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
        lp_full.gravity = Gravity.CENTER;
        container.setLayoutParams(lp_full);


        View maskView = new View(context);
        maskView.setLayoutParams(lp_full);
        maskView.setBackgroundColor(0x77333333);
        container.addView(maskView);
        maskView.setClickable(true);
        maskView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        //一个view的layoutParams用来告诉父视图,如何布局自己
        View contentView = new JsLoadingReminderStandard1(mContext);
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(300,300);
        lp.gravity = Gravity.CENTER;
        contentView.setLayoutParams(lp);
        container.addView(contentView);

        return container;
    }

    /**
     * 设置动画样式
     */
    public static void setAnimStyle(int id) {
        mLayoutParams_display.windowAnimations = id;
    }

    /**
     * 获取状态栏高度
     * @param context
     * @return
     */
    public static int getStatusBarHeight(Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        int height = resources.getDimensionPixelSize(resourceId);
        return height;
    }



//    /**
//     * 设置随意拖动
//     */
//    public X setDraggable() {
//        return setDraggable(new MovingDraggable());
//    }
//
//    /**
//     * 设置拖动规则
//     */
//    public X setDraggable(BaseDraggable draggable) {
//        // 当前是否设置了不可触摸，如果是就擦除掉这个标记
//        if (hasWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)) {
//            clearWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
//        }
//        mDraggable = draggable;
//        if (isShow()) {
//            update();
//            mDraggable.start(this);
//        }
//        return (X) this;
//    }

    /**
     * 限定显示时长
     */
//    public X setDuration(int duration) {
//        mDuration = duration;
//        if (isShow() && mDuration != 0) {
//            removeCallbacks();
//            postDelayed(new CancelRunnable(this), mDuration);
//        }
//        return (X) this;
//    }


    public static class JsDisplayStyle {
        public Boolean mb_isNeedMaskView;
        public Boolean mb_isMaskViewClickCancel;


        public Boolean mb_isReminderDisplaying;

        //一个style对应一个reminder.这里用来存储reminder的view.  reminder->style->mv_mask,所以style不要存储reminder本身,避免循环引用.
        public View mv_content;
        public View mv_mask;

        /**
         * 默认特性:
         * 没有maskView.
         * @return
         */
        public static JsDisplayStyle defaultStyle() {
            JsDisplayStyle style = new JsDisplayStyle();
            style.mb_isNeedMaskView = false;
            style.mb_isMaskViewClickCancel = false;
            return style;
        }
    }
}
